package jp.co.apl.haven.ao;

import java.sql.SQLException;

import jp.co.apl.haven.ao.entity.AnswerEntity;
import jp.co.apl.haven.ao.entity.BasicInfoEntity;
import jp.co.apl.haven.ao.entity.BasicInfoItemEntity;
import jp.co.apl.haven.ao.entity.BasicInfoSelectionItemEntity;
import jp.co.apl.haven.ao.entity.CategoryEntity;
import jp.co.apl.haven.ao.entity.EnqueteEntity;
import jp.co.apl.haven.ao.entity.QuestionEntity;
import jp.co.apl.haven.ao.entity.SelectionItemEntity;
import jp.co.apl.haven.inject.PersistenceModule;
import jp.co.apl.haven.persistence.Persistence;
import net.java.ao.EntityManager;
import net.java.ao.builder.EntityManagerBuilder;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Provider;

public class HavenAoModule extends PersistenceModule {

    private final Logger log = LoggerFactory.getLogger(HavenAoModule.class);

    public HavenAoModule() {
        super();
        url = "jdbc:postgresql://localhost:5432/haven";
        username = "haven";
        password = "haven";
    }

    public HavenAoModule(String url, String username, String password) {
        super(url, username, password);
    }

    @Override
    protected void doConfigure() {
        log.debug("doConfigure start");

        // ActiveObjects EntityManager
        bind(EntityManager.class)
            .toProvider(entityManagerProvider())
            .asEagerSingleton();

        log.debug("doConfigure end");
    }

    @Override
    protected Class<? extends Persistence> getPersistenceClass() {
        return PersistenceImpl.class;
    }

    private Provider<? extends EntityManager> entityManagerProvider() {
        return new Provider<EntityManager>() {
            @Override
            public EntityManager get() {
                log.info("create EntityManager (url = "
                    + url
                    + ", username = "
                    + username
                    + ")");

                EntityManager em =
                    EntityManagerBuilder
                        .url(url)
                        .username(username)
                        .password(password)
                        .auto()
                        .build();
                return em;
            }
        };
    }

    @SuppressWarnings("unchecked")
    public void migrate(EntityManager em) throws SQLException {
        log.debug("migrate start");

        em.migrate(
            EnqueteEntity.class,
            CategoryEntity.class,
            QuestionEntity.class,
            SelectionItemEntity.class,
            BasicInfoItemEntity.class,
            BasicInfoSelectionItemEntity.class,
            AnswerEntity.class,
            BasicInfoEntity.class);

        log.debug("migrate end");
    }

    public static void main(String[] args) throws SQLException {
        HavenAoModule module = new HavenAoModule();
        EntityManager em = module.entityManagerProvider().get();
        module.migrate(em);
    }

}
